package org.x.user.service.impl;


import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.x.common.config.BusinessException;
import org.x.common.config.Result;
import org.x.user.dto.CreateMenuDTO;
import org.x.user.dto.MenuQueryDTO;
import org.x.user.dto.MenuTreeNode;
import org.x.user.entity.SysUserEntity;
import org.x.user.service.ISysMenuService;
import org.x.user.entity.SysMenuEntity;
import org.x.user.mapper.SysMenuMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜单表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenuEntity> implements ISysMenuService {


    @Autowired
    private SysMenuMapper sysMenuMapper;

    //创建菜单
    @Override
    public int createMenu(CreateMenuDTO createMenuDTO) {
        SysMenuEntity sysMenuEntity = new SysMenuEntity();
        BeanUtils.copyProperties(createMenuDTO, sysMenuEntity);
        //检验菜单名称唯一性
        QueryWrapper nameWrapper = new QueryWrapper();
        nameWrapper.eq("name", createMenuDTO.getName())
                .eq("is_delete", 0);
        if (sysMenuMapper.selectCountByQuery(nameWrapper) > 0) {
            throw new BusinessException("菜单名称已存在");
        }
        //检验路径唯一性
        QueryWrapper pathWrapper = new QueryWrapper();
        pathWrapper.eq("path", createMenuDTO.getPath())
                .eq("is_delete", 0);
        if (sysMenuMapper.selectCountByQuery(pathWrapper) > 0) {
            throw new BusinessException("菜单路径已存在");
        }
        //菜单主键自增，我需要创建好后从数据库获取主键
        //sysMenuEntity.setId(null);

        sysMenuEntity.setIsDelete(0);       //逻辑删除字段   0 未删除  1 已删除
        sysMenuEntity.setHidden(true);     //菜单是否显示    false 显示  true 不显示
        sysMenuEntity.setCreatedTime(new Date());
        //插入数据
        sysMenuMapper.insert(sysMenuEntity);

        Long id = sysMenuEntity.getId();
        return id.intValue();
    }

    //修改菜单
    @Override
    public void update(CreateMenuDTO createMenuDTO) {
        //查询出要修改的菜单
        SysMenuEntity sysMenuEntity = sysMenuMapper.selectOneById(createMenuDTO.getMenuId());
        if (createMenuDTO == null || createMenuDTO.getMenuId() == null) {
            throw new BusinessException("当前菜单ID不存在");
        }
        //检验菜单名称唯一性
        QueryWrapper nameWrapper = new QueryWrapper();
        nameWrapper.eq("name", createMenuDTO.getName())
                .eq("is_delete", 0)
                .ne("id", createMenuDTO.getMenuId());
        if (sysMenuMapper.selectCountByQuery(nameWrapper) > 0) {
            throw new BusinessException("菜单名称已存在");
        }
        //检验路径唯一性
        QueryWrapper pathWrapper = new QueryWrapper();
        pathWrapper.eq("path", createMenuDTO.getPath())
                .eq("is_delete", 0)
                .ne("id", createMenuDTO.getMenuId());
        if (sysMenuMapper.selectCountByQuery(pathWrapper) > 0) {
            throw new BusinessException("菜单路径已存在");
        }
        // 当父节点ID变更时才需要检测循环
        if (!Objects.equals(sysMenuEntity.getParentId(), createMenuDTO.getParentId())) {
            // 调用循环检测方法：当前菜单ID和新父节点ID
            checkMenuCycle(createMenuDTO.getMenuId(), createMenuDTO.getParentId());
        }

        //赋值
        BeanUtils.copyProperties(createMenuDTO, sysMenuEntity);
        //修改
        sysMenuMapper.update(sysMenuEntity);
         //构建查询条件再查
//        QueryWrapper wrapper = new QueryWrapper();
//        wrapper.eq(SysMenuEntity::getId, createMenuDTO.getMenuId());
//        sysUserMapper.updateByQuery(sysUserEntity, wrapper);
    }
    public void checkMenuCycle(Long menuId, Long newParentId) {
        Set<Long> visited = new HashSet<>();
        Long currentId = newParentId;

        while (currentId != null && currentId != 0) {
            if (currentId.equals(menuId)) {
                throw new BusinessException("菜单层级设置形成循环");
            }
            if (visited.contains(currentId)) {
                throw new BusinessException("菜单层级设置形成循环引用");
            }
            visited.add(currentId);

            // 添加空指针检查
            SysMenuEntity parentMenu = sysMenuMapper.selectOneById(currentId);
            if (parentMenu == null) {
                break;
            }
            currentId = parentMenu.getParentId();
        }
    }

//    // 新增菜单权限过滤方法
//    public List<MenuTreeNode> filterMenuByPermission(List<MenuTreeNode> menuTree, Set<String> permissions) {
//        List<MenuTreeNode> result = new ArrayList<>();
//
//        for (MenuTreeNode node : menuTree) {
//            MenuTreeNode copy = node.copyWithoutChildren();
//
//            // 递归处理子节点
//            if (node.getChildren() != null && !node.getChildren().isEmpty()) {
//                List<MenuTreeNode> filteredChildren = filterMenuByPermission(node.getChildren(), permissions);
//                copy.setChildren(filteredChildren);
//            }
//
//            // 检查权限
//            if ((copy.getChildren() != null && !copy.getChildren().isEmpty()) ||
//                    hasMenuPermission(copy, permissions)) {
//                result.add(copy);
//            }
//        }
//        return result;
//    }

    // 权限检查辅助方法
    private boolean hasMenuPermission(MenuTreeNode menu, Set<String> permissions) {
        if (menu.getAclCode() == null) return true;
        return permissions.contains(menu.getAclCode());
    }

    //逻辑删除菜单
    @Override
    public void isDelete(Long id) {
        /**逻辑删除菜单（标记is_delete=1），用id查询出该数据，然后将is_delete=1 代表逻辑删除 */
        SysMenuEntity sysMenuEntity = sysMenuMapper.selectOneById(id);
        if (sysMenuEntity == null) {
            throw new BusinessException("当前菜单ID不存在");
        }
        if (sysMenuEntity.getIsDelete() == 1) {
            throw new BusinessException("当前菜单已删除");
        }
        //校验当前菜单下是否有子菜单
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysMenuEntity::getParentId, id);
        wrapper.eq(SysMenuEntity::getIsDelete, 0);
        if (sysMenuMapper.selectCountByQuery(wrapper) > 0) {
            throw new BusinessException("当前菜单下有子菜单，请先删除子菜单");
        }
//        //校验子菜单存在，先获取当前菜单的id,在获取所有菜单的parent_id,判断是否有等于当前菜单的id，如果有也一并删除。
//        QueryWrapper wrapper1 = new QueryWrapper();
//        wrapper1.eq(SysMenuEntity::getParentId, id);
//        List<SysMenuEntity> list = sysMenuMapper.selectListByQuery(wrapper1);
//        if (list != null && list.size() > 0) {
//            for (SysMenuEntity sysMenuEntity1 : list) {
//                sysMenuEntity1.setIsDelete(1);
//                sysMenuMapper.update(sysMenuEntity1);
//            }
//        }

        sysMenuEntity.setIsDelete(1);
        sysMenuMapper.update(sysMenuEntity);

    }

    //菜单分页查询
    @Override
    public Result pageList(MenuQueryDTO menuQueryDTO) {
        // 添加参数校验和默认值
        int pageNum = (menuQueryDTO.getPage() == null || menuQueryDTO.getPage() <= 0) ? 1 : menuQueryDTO.getPage();
        int size = (menuQueryDTO.getSize() == null || menuQueryDTO.getSize() <= 0) ? 10 : menuQueryDTO.getSize();

        //构建查询条件
        QueryWrapper wrapper = new QueryWrapper();
        if(menuQueryDTO.getName() != null && !menuQueryDTO.getName().isEmpty()){
            wrapper.like(SysMenuEntity::getName, menuQueryDTO.getName());
        }
        if(menuQueryDTO.getPath() != null && !menuQueryDTO.getPath().isEmpty()){
            wrapper.eq(SysMenuEntity::getPath, menuQueryDTO.getPath());
        }
        //is_delecr为1，表示删除了不予显示
        wrapper.eq(SysMenuEntity::getIsDelete, 0);

        Page<SysMenuEntity> page = sysMenuMapper.paginate(pageNum,size,wrapper);

        Map<String, Object> data = new HashMap<>();
        data.put("total", page.getTotalRow());
        data.put("records", page.getRecords());
        return Result.ok(data);
    }

    //菜单详情查询
    @Override
    public Object getByIddetail(Long id) {
        // 获取当前菜单信息
        SysMenuEntity menu = sysMenuMapper.selectOneById( id);
        if (menu == null) {
            throw new BusinessException("当前菜单ID不存在");
        }

        // 获取当前菜单的直接子菜单
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysMenuEntity::getParentId, id);
        wrapper.eq(SysMenuEntity::getIsDelete, 0);
        List<SysMenuEntity> children = sysMenuMapper.selectListByQuery(wrapper);
        menu.setChildren(children);

        return Result.ok(menu);
    }

    //菜单树查询
    @Override
    public Result tree() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysMenuEntity::getIsDelete, 0);

        List<SysMenuEntity> list = sysMenuMapper.selectListByQuery(wrapper);

        //构建树结构
        List<SysMenuEntity> menuTree = buildMenuTree(list);

        return Result.ok(menuTree);
    }
    //构建树结构
    public List<SysMenuEntity> buildMenuTree(List<SysMenuEntity> menuList) {
        // 1. 先找出所有根节点（parentId为0或null）
        List<SysMenuEntity> rootMenus = menuList.stream()
                .filter(menu -> menu.getParentId() == null || menu.getParentId() == 0)
                .collect(Collectors.toList());

        // 2. 为每个根节点递归构建子树
        rootMenus.forEach(menu -> buildChildren(menu, menuList));
        // 排序
        rootMenus.sort(Comparator.comparingInt(SysMenuEntity::getSort));
        return rootMenus;
    }
    //递归构建子树
    private void buildChildren(SysMenuEntity parent, List<SysMenuEntity> menuList) {
        List<SysMenuEntity> children = menuList.stream()
                .filter(menu -> menu.getParentId() != null && menu.getParentId().equals(parent.getId()))
                .collect(Collectors.toList());

        parent.setChildren(children);
        // 递归构建子节点的子树
        children.forEach(child -> buildChildren(child, menuList));
    }




}